#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
布局画布绘图模块
提供LayoutCanvas的绘图相关功能
"""

import os
from PyQt5.QtCore import Qt, QRect, QRectF
from PyQt5.QtGui import QPainter, QColor, QPen, QPixmap, QImage, QFont, QBrush

class LayoutCanvasDrawing:
    """布局画布绘图类"""
    
    def __init__(self, canvas):
        """初始化
        
        参数:
            canvas: LayoutCanvas实例
        """
        self.canvas = canvas
    
    def paint(self, event):
        """处理绘制事件"""
        super(self.canvas.__class__, self.canvas).paintEvent(event)
        
        if not self.canvas.root:
            return
        
        painter = QPainter(self.canvas)
        painter.setRenderHint(QPainter.Antialiasing)
        
        # 绘制背景网格
        self.draw_grid(painter)
        
        # 居中绘制预览区域
        canvas_width = self.canvas.width()
        canvas_height = self.canvas.height()
        
        # 计算缩放后的尺寸
        scaled_width = self.canvas.resolution[0] * self.canvas.scale_factor
        scaled_height = self.canvas.resolution[1] * self.canvas.scale_factor
        
        # 计算居中位置，并添加平移偏移量
        x_offset = (canvas_width - scaled_width) / 2 + self.canvas.pan_offset.x()
        y_offset = (canvas_height - scaled_height) / 2 + self.canvas.pan_offset.y()
        
        # 绘制预览区域边框
        painter.setPen(QPen(QColor(100, 100, 100), 2, Qt.SolidLine))
        painter.setBrush(QBrush(QColor(50, 50, 50)))
        preview_rect = QRect(int(x_offset), int(y_offset), int(scaled_width), int(scaled_height))
        painter.drawRect(preview_rect)
        
        # 在拖动状态下，使用简化的绘制以提高性能
        is_drag_mode = (self.canvas.dragging and self.canvas.drag_element 
                        and self.canvas.drag_start_rect and self.canvas.cached_parent_rect)
        
        # 如果使用最终渲染模式，绘制基准分辨率框（但在拖动时跳过以提高性能）
        if self.canvas.final_render_mode and not is_drag_mode:
            # 以不同颜色绘制基准分辨率框
            base_scale = min(scaled_width / self.canvas.base_resolution[0], 
                             scaled_height / self.canvas.base_resolution[1])
            base_width = self.canvas.base_resolution[0] * base_scale
            base_height = self.canvas.base_resolution[1] * base_scale
            
            # 居中绘制基准框
            base_x = x_offset + (scaled_width - base_width) / 2
            base_y = y_offset + (scaled_height - base_height) / 2
            
            # 绘制基准框
            painter.setPen(QPen(QColor(200, 100, 0), 1, Qt.DashLine))
            base_rect = QRect(int(base_x), int(base_y), int(base_width), int(base_height))
            painter.drawRect(base_rect)
            
            # 在基准框上方绘制标签
            painter.setPen(QColor(255, 150, 50))
            painter.drawText(QRect(int(base_x), int(base_y - 20), int(base_width), 20),
                           Qt.AlignCenter, 
                           f"基准分辨率: {self.canvas.base_resolution[0]}x{self.canvas.base_resolution[1]}")
        
        # 绘制分辨率信息
        painter.setPen(QColor(200, 200, 200))
        resolution_text = f"{self.canvas.resolution[0]}x{self.canvas.resolution[1]}"
        if self.canvas.final_render_mode:
            resolution_text += " (最终渲染模式)"
        if is_drag_mode:
            resolution_text += " (拖动模式)"
        painter.drawText(preview_rect.adjusted(5, 5, -5, -5), 
                       Qt.AlignRight | Qt.AlignTop, 
                       resolution_text)
        
        # 保存当前状态
        painter.save()
        
        # 设置裁剪区域，确保元素不会绘制到预览区域之外
        painter.setClipRect(preview_rect)
        
        # 平移到预览区域左上角
        painter.translate(x_offset, y_offset)
        
        # 缩放到目标分辨率
        painter.scale(self.canvas.scale_factor, self.canvas.scale_factor)
        
        # 如果根元素是GUILayout，则绘制其中的Window元素
        if self.canvas.root.tag == 'GUILayout':
            window = self.canvas.root.find('Window')
            if window is not None:
                # 在拖动模式下，可以考虑进一步优化渲染
                if is_drag_mode:
                    # 在拖动模式下，我们可以跳过一些复杂的渲染效果
                    painter.setRenderHint(QPainter.Antialiasing, False)  # 禁用抗锯齿以提高性能
                
                # 使用QRect而非QRectF避免类型错误
                self.draw_element(painter, window, QRect(0, 0, self.canvas.resolution[0], self.canvas.resolution[1]))
        else:
            # 直接绘制根元素
            if is_drag_mode:
                painter.setRenderHint(QPainter.Antialiasing, False)  # 禁用抗锯齿以提高性能
            
            # 使用QRect而非QRectF避免类型错误    
            self.draw_element(painter, self.canvas.root, QRect(0, 0, self.canvas.resolution[0], self.canvas.resolution[1]))
        
        # 恢复状态
        painter.restore()
        
        # 在拖动模式下显示性能提示
        if is_drag_mode:
            painter.setPen(QColor(255, 165, 0))
            painter.drawText(preview_rect.adjusted(5, 5, -5, -5), 
                           Qt.AlignLeft | Qt.AlignBottom, 
                           "性能模式：显示空方框")
    
    def draw_grid(self, painter):
        """绘制背景网格"""
        width, height = self.canvas.width(), self.canvas.height()
        
        # 设置网格颜色和笔
        grid_color = QColor(60, 60, 60)
        painter.setPen(QPen(grid_color, 1, Qt.DotLine))
        
        # 绘制水平线
        for y in range(0, height, 20):
            painter.drawLine(0, y, width, y)
        
        # 绘制垂直线
        for x in range(0, width, 20):
            painter.drawLine(x, 0, x, height)
    
    def draw_resize_handles(self, painter, rect):
        """绘制大小调整手柄
        
        参数:
            painter: QPainter对象
            rect: 元素矩形
        """
        # 将QRectF转换为QRect避免绘图类型错误
        if isinstance(rect, QRectF):
            rect = QRect(int(rect.x()), int(rect.y()), int(rect.width()), int(rect.height()))
            
        # 调整手柄大小
        handle_size = self.canvas.resize_handles_size
        half_size = handle_size // 2
        
        # 准备手柄位置
        handles = [
            QRect(rect.x() - half_size, rect.y() - half_size, handle_size, handle_size),                # 左上
            QRect(rect.x() + rect.width() // 2 - half_size, rect.y() - half_size, handle_size, handle_size),  # 上
            QRect(rect.x() + rect.width() - half_size, rect.y() - half_size, handle_size, handle_size),      # 右上
            QRect(rect.x() + rect.width() - half_size, rect.y() + rect.height() // 2 - half_size, handle_size, handle_size),  # 右
            QRect(rect.x() + rect.width() - half_size, rect.y() + rect.height() - half_size, handle_size, handle_size),      # 右下
            QRect(rect.x() + rect.width() // 2 - half_size, rect.y() + rect.height() - half_size, handle_size, handle_size),  # 下
            QRect(rect.x() - half_size, rect.y() + rect.height() - half_size, handle_size, handle_size),                # 左下
            QRect(rect.x() - half_size, rect.y() + rect.height() // 2 - half_size, handle_size, handle_size),  # 左
        ]
        
        # 设置绘制样式 - 使用更鲜明的颜色
        active_handle_color = QColor(255, 215, 0)  # 金色，活动手柄
        handle_color = QColor(220, 220, 220)  # 浅灰色，普通手柄
        
        # 保存原始笔和画刷
        old_pen = painter.pen()
        old_brush = painter.brush()
        
        # 设置粗边框，增加可见性
        painter.setPen(QPen(QColor(0, 0, 0), 2, Qt.SolidLine))
        
        # 绘制每个手柄
        for i, handle_rect in enumerate(handles):
            # 如果是当前活动的手柄，使用活动颜色
            if self.canvas.resizing and self.canvas.resize_handle == i:
                painter.setBrush(QBrush(active_handle_color))
            else:
                painter.setBrush(QBrush(handle_color))
                
            # 绘制带阴影效果的手柄
            # 首先绘制阴影
            shadow_rect = QRect(handle_rect.x() + 2, handle_rect.y() + 2, handle_rect.width(), handle_rect.height())
            painter.setPen(Qt.NoPen)
            painter.setBrush(QBrush(QColor(0, 0, 0, 100)))
            painter.drawRect(shadow_rect)
            
            # 然后绘制手柄本身
            painter.setPen(QPen(QColor(0, 0, 0), 2, Qt.SolidLine))
            painter.setBrush(QBrush(handle_color if not (self.canvas.resizing and self.canvas.resize_handle == i) else active_handle_color))
            painter.drawRect(handle_rect)
            
            # 在手柄中心添加小方块，提高可见性
            if self.canvas.resizing and self.canvas.resize_handle == i:
                center_rect = QRect(
                    handle_rect.x() + handle_rect.width() // 4,
                    handle_rect.y() + handle_rect.height() // 4,
                    handle_rect.width() // 2,
                    handle_rect.height() // 2
                )
                painter.setPen(Qt.NoPen)
                painter.setBrush(QBrush(QColor(0, 0, 0)))
                painter.drawRect(center_rect)
        
        # 恢复原始笔和画刷
        painter.setPen(old_pen)
        painter.setBrush(old_brush)
    
    def draw_element(self, painter, element, parent_rect):
        """递归绘制元素"""
        # 检查元素是否被隐藏
        if element in self.canvas.hidden_elements:
            return
            
        # 解析UnifiedAreaRect属性
        rect = self.canvas.utils.parse_area_rect(element, parent_rect)
        
        if rect is None:
            return
            
        # 将QRectF转换为QRect避免绘图类型错误
        if isinstance(rect, QRectF):
            rect = QRect(int(rect.x()), int(rect.y()), int(rect.width()), int(rect.height()))
        
        # 获取元素类型和名称
        element_type = element.get('Type', 'DefaultWindow')
        element_name = element.get('Name', 'Unknown')
        
        # 根据元素类型设置不同的颜色和样式
        bg_color = QColor(80, 80, 80, 100)  # 默认背景色
        border_color = QColor(200, 200, 200) # 默认边框色
        border_width = 1                     # 默认边框宽度
        
        # 如果是选中的元素，使用高亮样式
        if element == self.canvas.selected_element:
            border_color = QColor(255, 255, 0)
            border_width = 2
            bg_color = QColor(100, 100, 100, 120)
        # 如果是潜在选中元素(鼠标悬停)，使用悬停高亮样式
        elif element == self.canvas.potential_select_element:
            border_color = QColor(150, 200, 255)
            border_width = 1
            bg_color = QColor(80, 120, 180, 80)
        else:
            # 根据窗口类型设置不同的颜色
            if 'Button' in element_type:
                bg_color = QColor(50, 100, 150, 120)  # 按钮使用蓝色
            elif 'StaticImage' in element_type:
                bg_color = QColor(100, 50, 150, 100)  # 静态图像使用紫色
            elif 'StaticText' in element_type or 'Text' in element_type:
                bg_color = QColor(150, 150, 50, 100)  # 文本使用黄色
            elif 'Editbox' in element_type:
                bg_color = QColor(150, 50, 50, 100)   # 编辑框使用红色
        
        # 设置绘制样式
        painter.setPen(QPen(border_color, border_width, Qt.SolidLine))
        painter.setBrush(QBrush(bg_color))
        
        # 绘制元素矩形
        painter.drawRect(rect)
        
        # 如果是选中的元素且不在拖动或调整大小状态，绘制调整手柄
        if element == self.canvas.selected_element and not self.canvas.dragging:
            self.draw_resize_handles(painter, rect)
        
        # 检查拖动状态 - 如果正在拖动，只显示空方框，不加载和绘制图像
        if self.canvas.dragging and element == self.canvas.drag_element:
            # 绘制拖动指示器
            painter.setPen(QPen(QColor(255, 165, 0), 2, Qt.DashLine))  # 橙色虚线边框
            painter.setBrush(Qt.NoBrush)  # 无填充
            painter.drawRect(rect)
            
            # 在拖动的元素中心添加简单的文本标识
            painter.setPen(QColor(255, 255, 255))
            font = painter.font()
            old_font = QFont(font)
            font.setPointSize(8)
            font.setBold(True)
            painter.setFont(font)
            painter.drawText(rect, Qt.AlignCenter, f"{element_name} (拖动中)")
            painter.setFont(old_font)
            
            # 递归绘制子元素
            for child in element.findall('Window'):
                self.draw_element(painter, child, rect)
                
            return  # 拖动状态下跳过图像和其他复杂渲染
        
        # 查找是否有启用/禁用状态
        is_disabled = False
        for prop in element.findall('Property'):
            if prop.get('Name') == 'Disabled' and prop.get('Value').lower() == 'true':
                is_disabled = True
                break
        
        # 存储各种框架图像
        frame_images = {}
        background_image = None
        normal_image = None
        
        # 查找各种图像属性
        for prop in element.findall('Property'):
            prop_name = prop.get('Name')
            prop_value = prop.get('Value')
            
            # 收集框架图像
            if prop_name in ['TopFrameImage', 'BottomFrameImage', 'LeftFrameImage', 
                            'RightFrameImage', 'TopLeftFrameImage', 'TopRightFrameImage', 
                            'BottomLeftFrameImage', 'BottomRightFrameImage']:
                frame_images[prop_name] = prop_value
            # 背景图像
            elif prop_name == 'BackgroundImage':
                background_image = prop_value
            # 普通状态图像(按钮等)
            elif prop_name == 'olNormalImage' and not is_disabled:
                normal_image = prop_value
            # 禁用状态图像(按钮等)
            elif prop_name == 'olDisabledImage' and is_disabled:
                normal_image = prop_value
            # 其他常规图像
            elif prop_name == 'Image':
                if not normal_image:  # 如果没有找到状态图像，使用普通图像
                    normal_image = prop_value
        
        # 如果仍然没有找到图像，尝试其他常见图像属性
        if not normal_image:
            other_image_prop_names = [
                'olHoverImage', 'olPushedImage', 'olSelectedImage', 
                'olHighlightImage', 'MouseCursorImage', 'olMouseCursorImage'
            ]
            for prop_name in other_image_prop_names:
                for prop in element.findall('Property'):
                    if prop.get('Name') == prop_name:
                        normal_image = prop.get('Value')
                        break
                if normal_image:
                    break
        
        # 绘制背景图像
        if background_image:
            self.draw_image(painter, rect, background_image)
        
        # 绘制主图像
        if normal_image:
            self.draw_image(painter, rect, normal_image)
        
        # 绘制各种框架图像
        for frame_type, image_prop in frame_images.items():
            self.draw_frame_image(painter, rect, image_prop, frame_type)
        
        # 绘制元素信息
        text_color = QColor(255, 255, 255)
        if is_disabled:
            text_color = QColor(150, 150, 150)  # 禁用状态使用灰色文本
        
        painter.setPen(text_color)
        font = painter.font()
        old_font = QFont(font)
        font.setPointSize(8)
        painter.setFont(font)
        
        # 绘制元素名称和类型
        info_text = f"{element_name}"
        if rect.width() > 100:  # 如果矩形足够宽，显示更多信息
            info_text += f" ({element_type.split('/')[-1]})"
        
        painter.drawText(rect.adjusted(5, 5, -5, -5), Qt.AlignLeft | Qt.AlignTop, info_text)
        
        # 恢复原来的字体
        painter.setFont(old_font)
        
        # 递归绘制子元素
        for child in element.findall('Window'):
            self.draw_element(painter, child, rect)

    def draw_frame_image(self, painter, rect, image_prop, frame_type):
        """绘制框架图像
        
        参数:
            painter: QPainter对象
            rect: 元素矩形
            image_prop: 图像属性值
            frame_type: 框架类型
        """
        # 在拖动状态下不绘制图像
        if self.canvas.dragging:
            return
            
        # 尝试从缓存获取图像
        if image_prop in self.canvas.image_cache:
            pixmap = self.canvas.image_cache[image_prop]
        else:
            # 解析图像属性，格式为 "set:imageset_name image:image_name"
            try:
                # 支持"set:图集名 image:图片名"格式
                set_part = None
                image_part = None
                
                # 分开解析set和image部分
                parts = image_prop.split()
                for part in parts:
                    if part.startswith("set:"):
                        set_part = part[4:]  # 去掉"set:"前缀
                    elif part.startswith("image:"):
                        image_part = part[6:]  # 去掉"image:"前缀
                
                if not set_part or not image_part:
                    return
                
                imageset_name = set_part
                image_name = image_part
                
                # 获取图像信息和路径
                img_info = self.canvas.main_window.xml_handler.get_image_info(imageset_name, image_name)
                image_path = self.canvas.main_window.xml_handler.get_image_path(imageset_name)
                
                # 如果图集不存在或未加载、图像不存在、图像文件不存在
                if (imageset_name not in self.canvas.main_window.xml_handler.imagesets or 
                    not img_info or not image_path or not os.path.isfile(image_path)):
                    return
                
                # 加载图像
                full_image = QImage(image_path)
                if full_image.isNull():
                    return
                    
                # 从完整图像中裁剪出当前图像
                sub_image = full_image.copy(
                    img_info['XPos'], 
                    img_info['YPos'], 
                    img_info['Width'], 
                    img_info['Height']
                )
                
                # 转换为QPixmap并缓存
                pixmap = QPixmap.fromImage(sub_image)
                self.canvas.image_cache[image_prop] = pixmap
            except Exception as e:
                print(f"加载框架图像出错: {e}")
                return
        
        # 边框厚度(可以根据需要调整)
        border_thickness = min(rect.width() // 10, rect.height() // 10)
        border_thickness = max(border_thickness, 3)  # 确保至少有3个像素厚度
        
        # 角框大小
        corner_size = border_thickness * 2
        
        # 根据框架类型计算目标矩形和拉伸方式
        if frame_type == 'TopFrameImage':
            # 顶部框架：只横向拉伸，高度保持原样
            src_rect = QRect(0, 0, pixmap.width(), pixmap.height())
            target_rect = QRect(rect.x(), rect.y(), rect.width(), pixmap.height())
            painter.drawPixmap(target_rect, pixmap, src_rect)
            
        elif frame_type == 'BottomFrameImage':
            # 底部框架：只横向拉伸，高度保持原样
            src_rect = QRect(0, 0, pixmap.width(), pixmap.height())
            target_rect = QRect(rect.x(), rect.y() + rect.height() - pixmap.height(), 
                              rect.width(), pixmap.height())
            painter.drawPixmap(target_rect, pixmap, src_rect)
            
        elif frame_type == 'LeftFrameImage':
            # 左侧框架：只纵向拉伸，宽度保持原样
            src_rect = QRect(0, 0, pixmap.width(), pixmap.height())
            target_rect = QRect(rect.x(), rect.y(), pixmap.width(), rect.height())
            painter.drawPixmap(target_rect, pixmap, src_rect)
            
        elif frame_type == 'RightFrameImage':
            # 右侧框架：只纵向拉伸，宽度保持原样
            src_rect = QRect(0, 0, pixmap.width(), pixmap.height())
            target_rect = QRect(rect.x() + rect.width() - pixmap.width(), rect.y(), 
                              pixmap.width(), rect.height())
            painter.drawPixmap(target_rect, pixmap, src_rect)
            
        elif frame_type == 'TopLeftFrameImage':
            # 左上角框架：不拉伸，保持原始尺寸
            src_rect = QRect(0, 0, pixmap.width(), pixmap.height())
            target_rect = QRect(rect.x(), rect.y(), pixmap.width(), pixmap.height())
            painter.drawPixmap(target_rect, pixmap, src_rect)
            
        elif frame_type == 'TopRightFrameImage':
            # 右上角框架：不拉伸，保持原始尺寸
            src_rect = QRect(0, 0, pixmap.width(), pixmap.height())
            target_rect = QRect(rect.x() + rect.width() - pixmap.width(), rect.y(), 
                              pixmap.width(), pixmap.height())
            painter.drawPixmap(target_rect, pixmap, src_rect)
            
        elif frame_type == 'BottomLeftFrameImage':
            # 左下角框架：不拉伸，保持原始尺寸
            src_rect = QRect(0, 0, pixmap.width(), pixmap.height())
            target_rect = QRect(rect.x(), rect.y() + rect.height() - pixmap.height(), 
                              pixmap.width(), pixmap.height())
            painter.drawPixmap(target_rect, pixmap, src_rect)
            
        elif frame_type == 'BottomRightFrameImage':
            # 右下角框架：不拉伸，保持原始尺寸
            src_rect = QRect(0, 0, pixmap.width(), pixmap.height())
            target_rect = QRect(rect.x() + rect.width() - pixmap.width(), 
                              rect.y() + rect.height() - pixmap.height(),
                              pixmap.width(), pixmap.height())
            painter.drawPixmap(target_rect, pixmap, src_rect)
    
    def draw_image(self, painter, rect, image_prop):
        """绘制图像"""
        # 将QRectF转换为QRect类型，修复类型不匹配问题
        if isinstance(rect, QRectF):
            rect = QRect(int(rect.x()), int(rect.y()), int(rect.width()), int(rect.height()))
            
        # 检查是否在拖动状态 - 在此方法内部再次检查，以确保安全
        if self.canvas.dragging:
            # 在拖动状态下，只绘制占位框，不加载和绘制实际图像
            painter.setPen(QPen(QColor(100, 100, 100), 1, Qt.DotLine))
            painter.setBrush(QBrush(QColor(50, 50, 150, 50)))
            painter.drawRect(rect)
            return
            
        # 尝试从缓存获取图像
        if image_prop in self.canvas.image_cache:
            # 直接使用缓存的图像
            pixmap = self.canvas.image_cache[image_prop]
            painter.drawPixmap(rect, pixmap)
            return
        
        # 解析图像属性，格式为 "set:imageset_name image:image_name"
        try:
            # 支持"set:图集名 image:图片名"格式
            set_part = None
            image_part = None
            
            # 分开解析set和image部分
            parts = image_prop.split()
            for part in parts:
                if part.startswith("set:"):
                    set_part = part[4:]  # 去掉"set:"前缀
                elif part.startswith("image:"):
                    image_part = part[6:]  # 去掉"image:"前缀
            
            if not set_part or not image_part:
                raise ValueError(f"无效的图像属性格式: {image_prop}")
            
            imageset_name = set_part
            image_name = image_part
            
            # 获取图像信息和路径
            img_info = self.canvas.main_window.xml_handler.get_image_info(imageset_name, image_name)
            image_path = self.canvas.main_window.xml_handler.get_image_path(imageset_name)
            
            # 如果图集不存在或未加载
            if imageset_name not in self.canvas.main_window.xml_handler.imagesets:
                painter.setPen(QPen(QColor(255, 165, 0), 1, Qt.DashLine))  # 橙色
                painter.setBrush(QBrush(QColor(255, 165, 0, 50)))
                painter.drawRect(rect)
                
                font = painter.font()
                old_font = QFont(font)
                font.setPointSize(8)
                painter.setFont(font)
                
                painter.setPen(QColor(255, 255, 255))
                painter.drawText(rect, Qt.AlignCenter, f"未加载图集: {imageset_name}")
                
                painter.setFont(old_font)
                return
            
            # 如果图像不存在
            if not img_info:
                painter.setPen(QPen(QColor(255, 0, 0), 1, Qt.DashLine))  # 红色
                painter.setBrush(QBrush(QColor(255, 0, 0, 50)))
                painter.drawRect(rect)
                
                font = painter.font()
                old_font = QFont(font)
                font.setPointSize(8)
                painter.setFont(font)
                
                painter.setPen(QColor(255, 255, 255))
                painter.drawText(rect, Qt.AlignCenter, f"图像不存在: {image_name}")
                
                painter.setFont(old_font)
                return
            
            # 如果图像文件不存在
            if not image_path or not os.path.isfile(image_path):
                painter.setPen(QPen(QColor(0, 255, 255), 1, Qt.DashLine))  # 青色
                painter.setBrush(QBrush(QColor(0, 100, 200, 100)))
                painter.drawRect(rect)
                
                font = painter.font()
                old_font = QFont(font)
                font.setPointSize(8)
                painter.setFont(font)
                
                painter.setPen(QColor(255, 255, 255))
                painter.drawText(rect, Qt.AlignCenter, f"{imageset_name}:{image_name}\n图像文件未找到")
                
                painter.setFont(old_font)
                return
            
            # 尝试加载和绘制实际图像
            try:
                # 加载完整图像
                full_image = QImage(image_path)
                if not full_image.isNull():
                    # 从完整图像中裁剪出当前图像
                    sub_image = full_image.copy(
                        img_info['XPos'], 
                        img_info['YPos'], 
                        img_info['Width'], 
                        img_info['Height']
                    )
                    
                    # 将子图像转换为QPixmap并缓存
                    pixmap = QPixmap.fromImage(sub_image)
                    self.canvas.image_cache[image_prop] = pixmap
                    
                    # 绘制图像
                    painter.drawPixmap(rect, pixmap)
                    return
                else:
                    raise Exception("无法加载图像文件")
            except Exception as e:
                print(f"绘制图像出错: {e}")
                
                # 出错时显示占位符
                painter.setPen(QPen(QColor(255, 0, 0), 1, Qt.DashLine))
                painter.setBrush(QBrush(QColor(200, 0, 0, 100)))
                painter.drawRect(rect)
                
                font = painter.font()
                old_font = QFont(font)
                font.setPointSize(8)
                painter.setFont(font)
                
                painter.setPen(QColor(255, 255, 255))
                painter.drawText(rect, Qt.AlignCenter, f"图像加载错误:\n{str(e)[:20]}...")
                
                painter.setFont(old_font)
                return
        except Exception as e:
            print(f"解析图像属性出错: {e}")
            painter.setPen(QPen(QColor(255, 0, 0), 1, Qt.DashLine))
            painter.drawRect(rect)
            
            font = painter.font()
            old_font = QFont(font)
            font.setPointSize(8)
            painter.setFont(font)
            
            painter.setPen(QColor(255, 255, 255))
            painter.drawText(rect, Qt.AlignCenter, f"图像属性错误:\n{str(e)[:20]}...")
            
            painter.setFont(old_font) 